package net.arogarth.aws.android.lib;

import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import net.arogarth.aws.android.lib.def.Architecture;
import net.arogarth.aws.android.lib.def.Ec2InstanceState;
import net.arogarth.aws.android.lib.def.ResourceType;
import net.arogarth.aws.android.lib.models.AvailabilityZoneInfo;
import net.arogarth.aws.android.lib.models.Ec2Ami;
import net.arogarth.aws.android.lib.models.Ec2Ebs;
import net.arogarth.aws.android.lib.models.Ec2ElasticIp;
import net.arogarth.aws.android.lib.models.Ec2ElasticIp.Ec2Domain;
import net.arogarth.aws.android.lib.models.Ec2Instance;
import net.arogarth.aws.android.lib.models.Ec2Snapshot;
import net.arogarth.aws.android.lib.models.Ec2Tag;
import net.arogarth.aws.android.lib.models.RegionInfo;

public class AmazonEc2 extends AmazonAWS {
	public AmazonEc2() {
		super();
		
		this.service = "ec2";
		
		if(!AwsSettings.getAwsRegion().equals(""))
			this.service += "." + AwsSettings.getAwsRegion();
		
		this.version = "2011-07-15";
	}

	public List<Ec2Instance> descriptInstances() throws AwsRequestException {
		List<Ec2Instance> Ec2Instances = new ArrayList<Ec2Instance>();

		params.put("Action", "DescribeInstances");
		Element root = this.execute();

		XPath xpath = XPathFactory.newInstance().newXPath();

		try {
			NodeList items = (NodeList) xpath.evaluate("//instancesSet/*",
					root, XPathConstants.NODESET);

			for (int i = 0; i < items.getLength(); i++) {
				Ec2Instance Ec2Instance = new Ec2Instance();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();

				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();

					if (property.getFirstChild() == null)
						continue;
					String value = property.getFirstChild().getNodeValue();

					if (name.equalsIgnoreCase("instanceId")) {
						Ec2Instance.setInstanceId(value);
					} else if (name.equalsIgnoreCase("architecture")) {
						if (value.equalsIgnoreCase("i386"))
							Ec2Instance.setArchitecture(Architecture.i386);
						else
							Ec2Instance.setArchitecture(Architecture.x86_64);
					} else if (name.equalsIgnoreCase("imageId")) {
						Ec2Instance.setAmiId(value);
					} else if (name.equalsIgnoreCase("privateDnsName")) {
						Ec2Instance.setPrivateDnsName(value);
					} else if (name.equalsIgnoreCase("dnsName")) {
						Ec2Instance.setPublicDnsName(value);
					} else if (name.equalsIgnoreCase("keyName")) {
						Ec2Instance.setKeyName(value);
					} else if (name.equalsIgnoreCase("amiLaunchIndex")) {
						Ec2Instance.setAmiLaunchIndex(value);
					} else if (name.equalsIgnoreCase("instanceType")) {
						Ec2Instance.setInstanceType(value);
					} else if (name.equalsIgnoreCase("launchTime")) {
						Ec2Instance.setInstanceLaunchTime(value);
					} else if (name.equalsIgnoreCase("kernelId")) {
						Ec2Instance.setKernelId(value);
					} else if (name.equalsIgnoreCase("ramdiskId")) {
						Ec2Instance.setRamDiskId(value);
					} else if (name.equalsIgnoreCase("privateIpAddress")) {
						Ec2Instance.setPrivateIpAddress(value);
					} else if (name.equalsIgnoreCase("ipAddress")) {
						Ec2Instance.setPublicIpAddress(value);
					} else if (name.equalsIgnoreCase("rootDeviceType")) {
						Ec2Instance.setRootDeviceType(value);
					} else if (name.equalsIgnoreCase("tagSet")) {
						
						NodeList tagItems = ( (Element) property ).getElementsByTagName("item");
						
						for(int k=0; k < tagItems.getLength(); k++) {
							Element e = (Element) tagItems.item(k);
							
							String _key = e.getElementsByTagName("key").item(0).getTextContent();
							String _value = e.getElementsByTagName("value").item(0).getTextContent();
							
							Ec2Instance.getTagSet().put(_key, _value);
						}
						
					} else if (name.equalsIgnoreCase("rootDeviceName")) {
						Ec2Instance.setRootDeviceName(value);
					} else if (name.equalsIgnoreCase("instanceState")) {
						Node c = property.getFirstChild();
						do {
							if (c.getNodeName().equalsIgnoreCase("name")) {
								String code = c.getFirstChild().getNodeValue();
								if (code.equalsIgnoreCase("pending")) {
									Ec2Instance
											.setInstanceState(Ec2InstanceState.PENDING);
								} else if (code.equalsIgnoreCase("running")) {
									Ec2Instance
											.setInstanceState(Ec2InstanceState.RUNNING);
								} else if (code
										.equalsIgnoreCase("shutting down")) {
									Ec2Instance
											.setInstanceState(Ec2InstanceState.SHUTTING_DOWN);
								} else if (code.equalsIgnoreCase("terminated")) {
									Ec2Instance
											.setInstanceState(Ec2InstanceState.TERMINATED);
								} else if (code.equalsIgnoreCase("stopping")) {
									Ec2Instance
											.setInstanceState(Ec2InstanceState.STOPPING);
								} else if (code.equalsIgnoreCase("stopped")) {
									Ec2Instance
											.setInstanceState(Ec2InstanceState.STOPPED);
								} else {
									Ec2Instance
											.setInstanceState(Ec2InstanceState.UNKNOWN);
								}
								break;
							}
							// if(c.getNodeName().equalsIgnoreCase("code") ) {
							// String code = c.getFirstChild().getNodeValue();
							// if(code.equalsIgnoreCase("0")) {
							// Ec2Instance.setInstanceState(Ec2InstanceState.PENDING);
							// } else if(code.equalsIgnoreCase("16")) {
							// Ec2Instance.setInstanceState(Ec2InstanceState.RUNNING);
							// } else if(code.equalsIgnoreCase("32")) {
							// Ec2Instance.setInstanceState(Ec2InstanceState.SHUTTING_DOWN);
							// } else if(code.equalsIgnoreCase("48")) {
							// Ec2Instance.setInstanceState(Ec2InstanceState.TERMINATED);
							// } else if(code.equalsIgnoreCase("64")) {
							// Ec2Instance.setInstanceState(Ec2InstanceState.STOPPING);
							// } else if(code.equalsIgnoreCase("80")) {
							// Ec2Instance.setInstanceState(Ec2InstanceState.STOPPED);
							// } else {
							// Ec2Instance.setInstanceState(Ec2InstanceState.UNKNOWN);
							// }
							// break;
							// }
						} while ((c = c.getNextSibling()) != null);

						// } else if (name.equalsIgnoreCase("")) {
						// } else if (name.equalsIgnoreCase("")) {
						// } else if (name.equalsIgnoreCase("")) {
						// } else if (name.equalsIgnoreCase("")) {
						// } else if (name.equalsIgnoreCase("")) {

					}
				}

				Ec2Instances.add(Ec2Instance);
			}
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return Ec2Instances;
	}

	public void startInstance(Ec2Instance instance) throws AwsRequestException {
		params.put("Action", "StartInstances");
		params.put("InstanceId.1", instance.getInstanceId());

		this.execute();

		instance.setInstanceState(Ec2InstanceState.PENDING);
	}

	public void stopInstance(Ec2Instance instance) throws AwsRequestException {
		params.put("Action", "StopInstances");
		params.put("InstanceId.1", instance.getInstanceId());
		this.execute();

		instance.setInstanceState(Ec2InstanceState.STOPPING);
	}

	public void terminateInstance(Ec2Instance instance) throws AwsRequestException 
			{
		params.put("Action", "TerminateInstances");
		params.put("InstanceId.1", instance.getInstanceId());
		this.execute();

		instance.setInstanceState(Ec2InstanceState.STOPPING);
	}

	public List<Ec2Snapshot> descriptSnapshots() throws AwsRequestException {
		List<Ec2Snapshot> Ec2Snapshots = new ArrayList<Ec2Snapshot>();

		params.put("Action", "DescribeSnapshots");
		params.put("Owner.1", "self");
		Element root = this.execute();

		XPath xpath = XPathFactory.newInstance().newXPath();

		try {
			NodeList items = (NodeList) xpath.evaluate("//snapshotSet/*", root,
					XPathConstants.NODESET);

			for (int i = 0; i < items.getLength(); i++) {
				Ec2Snapshot Ec2Snapshot = new Ec2Snapshot();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();

				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();
					if (property.getFirstChild() == null)
						continue;
					String value = property.getFirstChild().getNodeValue();

					if (name.equalsIgnoreCase("snapshotId")) {
						Ec2Snapshot.setSnapshotId(value);
					} else if (name.equalsIgnoreCase("valuemId")) {
						Ec2Snapshot.setVolumeId(value);
					} else if (name.equalsIgnoreCase("status")) {
						Ec2Snapshot.setStatus(value);
					} else if (name.equalsIgnoreCase("startTime")) {
						Ec2Snapshot.setStartTime(value);
					} else if (name.equalsIgnoreCase("progress")) {
						Ec2Snapshot.setProgress(value);
					} else if (name.equalsIgnoreCase("ownerId")) {
						Ec2Snapshot.setOwnerId(value);
					} else if (name.equalsIgnoreCase("volumeSize")) {
						Ec2Snapshot.setVolumeSize(Integer.parseInt(value));
					} else if (name.equalsIgnoreCase("description")) {
						Ec2Snapshot.setDescription(value);
					}
				}

				Ec2Snapshots.add(Ec2Snapshot);
			}
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return Ec2Snapshots;
	}

	public List<Ec2Tag> descriptTags() throws AwsRequestException {
		List<Ec2Tag> ec2Tags = new ArrayList<Ec2Tag>();

		params.put("Action", "DescribeTags");
		Element root = this.execute();

		XPath xpath = XPathFactory.newInstance().newXPath();

		try {
			NodeList items = (NodeList) xpath.evaluate("//tagSet/*", root,
					XPathConstants.NODESET);
			for (int i = 0; i < items.getLength(); i++) {
				Ec2Tag ec2Tag = new Ec2Tag();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();

				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();

					if (name.equalsIgnoreCase("resourceId")) {
						ec2Tag.setResourceId(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("resourceType")) {
						String resourceType = property.getFirstChild()
								.getNodeValue();

						if (resourceType.equalsIgnoreCase("instance"))
							ec2Tag.setResourceType(ResourceType.INSTANCE);
						else if (resourceType.equalsIgnoreCase("image"))
							ec2Tag.setResourceType(ResourceType.IMAGE);
						else
							ec2Tag.setResourceType(ResourceType.UNKNOWN);

					} else if (name.equalsIgnoreCase("key")) {
						ec2Tag.setKey(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("value")) {
						ec2Tag.setValue(property.getFirstChild().getNodeValue());
					}
				}

				ec2Tags.add(ec2Tag);
			}
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ec2Tags;
	}

	public List<Ec2Ami> describeImages() throws AwsRequestException {
		List<Ec2Ami> amazonMachineImages = new ArrayList<Ec2Ami>();

		params.put("Filter.1.Name", "is-public");
		params.put("Filter.1.Value", "false");
		params.put("Action", "DescribeImages");
		Element root = this.execute();

		XPath xpath = XPathFactory.newInstance().newXPath();

		try {
			NodeList items = (NodeList) xpath.evaluate("//imagesSet/*", root,
					XPathConstants.NODESET);
			for (int i = 0; i < items.getLength(); i++) {
				Ec2Ami machineImage = new Ec2Ami();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();

				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();

					if (name.equalsIgnoreCase("imageId")) {
						machineImage.setImageId(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("imageLocation")) {
						machineImage.setImageLocation(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("name")) {
						machineImage.setName(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("imageState")) {
						machineImage.setImageState(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("imageOwnerId")) {
						machineImage.setImageOwnerId(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("isPublic")) {
						machineImage.setIsPublic(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("architecture")) {
						machineImage.setArchitecture(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("imageType")) {
						machineImage.setImageType(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("platform")) {
						machineImage.setPlatform(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("imageOwnerAlias")) {
						machineImage.setImageOwnerAlias(property
								.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("rootDeviceType")) {
						machineImage.setRootDeviceType(property.getFirstChild()
								.getNodeValue());
					} else if (name.equalsIgnoreCase("blockDeviceMapping")) {
						machineImage.setBlockDeviceMapping(property
								.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("virtualizationType")) {
						machineImage.setVirtualizationType(property
								.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("hypervisor")) {
						machineImage.setHypervisor(property.getFirstChild()
								.getNodeValue());
					}
				}

				amazonMachineImages.add(machineImage);
			}
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return amazonMachineImages;
	}

	public List<Ec2Ebs> describeVolumes() throws AwsRequestException {
		List<Ec2Ebs> ec2Volumes = new ArrayList<Ec2Ebs>();

		params.put("Action", "DescribeVolumes");
		Element root = this.execute();

		XPath xpath = XPathFactory.newInstance().newXPath();

		try {
			NodeList items = (NodeList) xpath.evaluate("//volumeSet/*", root, XPathConstants.NODESET);

			for (int i = 0; i < items.getLength(); i++) {
				Ec2Ebs volume = new Ec2Ebs();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();

				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					if(property.getFirstChild() == null) continue;
					
					String name = property.getNodeName();

					if (name.equalsIgnoreCase("volumeId")) {
						volume.setVolumeId(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("name")) {
						volume.setName(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("size")) {
						volume.setSize(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("attachmentSet")) {
						Node m = property.getFirstChild();
						if(m != null) {
							do {
								Node n = m.getFirstChild();
								if(n == null) continue;
								
								do {
									name = n.getNodeName();
									if (name.equalsIgnoreCase("device")) {
										volume.setDevice(n.getFirstChild().getNodeValue());
									} else if (name.equalsIgnoreCase("instanceid")) {
										volume.setInstanceId(n.getFirstChild().getNodeValue());
									}
								} while((n = n.getNextSibling()) != null);
							} while((m = m.getNextSibling()) != null);
						}
					} else if (name.equalsIgnoreCase("snapshotId")) {
						volume.setSnapshotId(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("availabilityZone")) {
						volume.setAvailabilityZone(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("status")) {
						volume.setStatus(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("createTime")) {
						volume.setCreateTime(property.getFirstChild().getNodeValue());
					}
				}
				
				ec2Volumes.add(volume);
			}
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		
		return ec2Volumes;
	}

	/**
	 * Delete a Volume by Id
	 * 
	 * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteVolume.html">API-Referenz</a>
	 * @param volumeId
	 * @throws AwsRequestException
	 */
	public void deleteVolume(String volumeId) throws AwsRequestException {
		params.put("Action", "DeleteVolume");
		params.put("VolumeId", volumeId);
		
		this.execute();
	}
	
	/**
	 * 
	 * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AttachVolume.html">API-Referenz</a>
	 * @param volumeId
	 * @param instanceId
	 * @param device
	 * @throws AwsRequestException
	 */
	public void attachVolume(String volumeId, String instanceId, String device) throws AwsRequestException {
		params.put("Action", "AttachVolume");
		params.put("InstanceId", instanceId);
		params.put("VolumeId", volumeId);
		params.put("Device", device);
		
		this.execute();
	}
	
	/**
	 * 
	 * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DetachVolume.html">API-Referenz</a>
	 * @param volumeId
	 * @throws AwsRequestException
	 */
	public void detachVolume(String volumeId) throws AwsRequestException {
		params.put("Action", "DetachVolume");
		params.put("VolumeId", volumeId);
		
		this.execute();
	}

	/**
	 * Create a Snapshot from the given EBS-Volume
	 * 
	 * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSnapshot.html">API-Referenz</a>
	 * @param volumeId
	 * @throws AwsRequestException
	 */
	public void createSnapshot(String volumeId) throws AwsRequestException {
		createSnapshot(volumeId, "");
	}
	
	/**
	 * Create a Snapshot from the given EBS-Volume
	 * 
	 * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSnapshot.html">API-Referenz</a>
	 * @param volumeId
	 * @throws AwsRequestException
	 */
	public void createSnapshot(String volumeId, String description) throws AwsRequestException {
		params.put("Action", "CreateSnapshot");
		params.put("VolumeId", volumeId);
		
		if(!description.equals(""))
			params.put("Description", description);
		
		this.execute();
	}
	
	/**
	 * Deregister the given Image
	 * 
	 * @param imageId
	 */
	public void deregisterImage(String imageId) {
		params.put("Action", "DeregisterImage");
		params.put("ImageId", imageId);
		
		try {
			this.execute();
		} catch (AwsRequestException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Register a Snapshot as new AMI
	 * @param name
	 */
	public void registerImage(String snapshotId, String name) {
		params.put("Name", name);
		params.put("Action", "RegisterImage");
		
		params.put("RootDeviceName", "/dev/sda1");
		
		for (int i=0; i < 1; i++) {
			params.put(
					String.format("BlockDeviceMapping.%s.DeviceName", i), "/dev/sda1");
//			params.put(
//					String.format("BlockDeviceMapping.%s.VirtualName", i), "/dev/sda1");
			params.put(
					String.format("BlockDeviceMapping.%s.Ebs.SnapshotId", i), snapshotId);
//			params.put(
//					String.format("BlockDeviceMapping.%s.Ebs.VolumeSize", i), "/dev/sda1");
//			params.put(
//					String.format("BlockDeviceMapping.%s.Ebs.NoDevice", i), "true");
//			params.put(
//					String.format("BlockDeviceMapping.%s.Ebs.DeleteOnTermination", i), "false");
		}
		
		try {
			this.execute();
		} catch (AwsRequestException e) {
			e.printStackTrace();
		}
	}
	
	public List<AvailabilityZoneInfo> describeAvailabilityZones() throws AwsRequestException {
		params.put("Action", "DescribeAvailabilityZones");

		List<AvailabilityZoneInfo> zones = new ArrayList<AvailabilityZoneInfo>();
		
		try {
			Element root = this.execute();

			XPath xpath = XPathFactory.newInstance().newXPath();

			NodeList items = (NodeList) xpath.evaluate("//availabilityZoneInfo/*", root, XPathConstants.NODESET);

			for (int i = 0; i < items.getLength(); i++) {
				AvailabilityZoneInfo zone = new AvailabilityZoneInfo();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();

				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					if(property.getFirstChild() == null) continue;
					
					String name = property.getNodeName();

					if (name.equalsIgnoreCase("zoneName")) {
						zone.setZoneName(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("zoneState")) {
						zone.setZoneState(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("regionName")) {
						zone.setRegionName(property.getFirstChild().getNodeValue());
					}
				}
				
				zones.add(zone);
			}
		} catch (Exception e) {
			
		}
		
		return zones;
	}
	
	public List<RegionInfo> describeRegions() throws AwsRequestException {
		params.put("Action", "DescribeRegions");
		
		List<RegionInfo> regions = new ArrayList<RegionInfo>();
		
		try {
			Element root = this.execute();
			
			XPath xpath = XPathFactory.newInstance().newXPath();
			
			NodeList items = (NodeList) xpath.evaluate("//regionInfo/*", root, XPathConstants.NODESET);
			
			for (int i = 0; i < items.getLength(); i++) {
				RegionInfo region = new RegionInfo();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();
				
				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					if(property.getFirstChild() == null) continue;
					
					String name = property.getNodeName();
					
					if (name.equalsIgnoreCase("regionName")) {
						region.setRegionName(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("regionEndpoint")) {
//						region.setRegionName(property.getFirstChild().getNodeValue());
					}
				}
				
				regions.add(region);
			}
		} catch (Exception e) {
			
		}
		
		return regions;
	}
	
	public void createVolume(String size, String availabilityZone) throws AwsRequestException {
		params.put("Size", size);
		params.put("AvailabilityZone", availabilityZone);
		params.put("Action", "CreateVolume");
		
		this.execute();
	}
	
	////////////////////////////////////////////////////////////////////////
	// EC2 ElaticIp
	////////////////////////////////////////////////////////////////////////
	
	public List<Ec2ElasticIp> describeAddresses() throws AwsRequestException {
		this.params.put("Action", "DescribeAddresses");
		List<Ec2ElasticIp> elasticIps = new ArrayList<Ec2ElasticIp>();
		
		try {
			Element root = this.execute();
			
			XPath xpath = XPathFactory.newInstance().newXPath();
			
			NodeList items = (NodeList) xpath.evaluate("//addressesSet/*", root, XPathConstants.NODESET);
			
			for (int i = 0; i < items.getLength(); i++) {
				Ec2ElasticIp elip = new Ec2ElasticIp();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();
				
				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					if(property.getFirstChild() == null) continue;
					
					String name = property.getNodeName();
					
					if (name.equalsIgnoreCase("publicIp")) {
						elip.setPublicIp(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("domain")) {
						String domain = property.getFirstChild().getNodeValue();
						if(domain == "vpc")
							elip.setDomain(Ec2Domain.VPC);
						else
							elip.setDomain(Ec2Domain.EC2);
					} else if (name.equalsIgnoreCase("instanceId")) {
						elip.setInstanceId(property.getFirstChild().getNodeValue());
					}
				}
				
				elasticIps.add(elip);
			}
		} catch (XPathExpressionException e) { }
		
		return elasticIps;
	}
	
	public void associateAddress(String publicIp, String instanceId) throws AwsRequestException {
		this.params.put("Action", "AssociateAddress");
		this.params.put("PublicIp", publicIp);
		this.params.put("InstanceId", instanceId);
		this.execute();
	}
	
	public void disassociateAddress(String publicIp) throws AwsRequestException {
		this.params.put("Action", "DisassociateAddress");
		this.params.put("PublicIp", publicIp);
		this.execute();
	}
	
	public void allocateAddress(Ec2Domain domain) throws AwsRequestException {
		if(domain.equals(Ec2Domain.VPC)) this.params.put("Domain", "vpc");
		else this.params.put("Domain", "ec2");
		
		this.params.put("Action", "AllocateAddress");
		
		this.execute();
	}
}
